﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
using System.Runtime.Serialization;
using AqueleAjax.UI;

namespace AqueleAjax.UI.Controls
{
    [ParseChildren(true)]
    [PersistChildren(false)]
    public class AutoCompleteResult : Control, INamingContainer
    {
        public event AutoCompleteResultEventHandler ItemDataBound;
        public event AutoCompleteResultCommandEventHandler ItemCommand;

        private AutoComplete _autoComplete;

        public AutoComplete AutoComplete
        {
            get { return this._autoComplete; }
            set { this._autoComplete = value; }
        }
        
        private Repeater _repeater;

        private Repeater Repeater
        {
            get
            {
                if (this._repeater == null)
                {
                    this._repeater = new Repeater();
                }

                return this._repeater; 
            }
            set { this._repeater = value; }
        }

        private AutoCompleteResultItemCollection _items;

        public AutoCompleteResultItemCollection Items
        {
            get 
            {
                if (this._items == null)
                {
                    this._items = new AutoCompleteResultItemCollection();
                }

                return this._items; 
            }
            private set
            {
                this._items = value; 
            }
        }

        private StringCollection _dataKeyValues;

        private StringCollection DataKeyValues
        {
            get 
            {
                if (this._dataKeyValues == null)
                {
                    this._dataKeyValues = new StringCollection();
                }

                return this._dataKeyValues; 
            }
            set { this._dataKeyValues = value; }
        }

        public virtual object DataSource
        {
            get { return this.Repeater.DataSource; }
            set { this.Repeater.DataSource = value; }
        }

        [TemplateInstance(TemplateInstance.Single)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public virtual ITemplate ItemTemplate 
        {
            get { return this.Repeater.ItemTemplate; }
            set { this.Repeater.ItemTemplate = value; }
        }

        [TemplateInstance(TemplateInstance.Single)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public virtual ITemplate SeparatorTemplate
        {
            get { return this.Repeater.SeparatorTemplate; }
            set { this.Repeater.SeparatorTemplate = value; }
        }

        public override void DataBind()
        {
            this.Repeater.DataSource = this.DataSource;
            this.Repeater.DataBind();
            this.AddItems();
        }

        protected override void Render(HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
            writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);

            writer.RenderBeginTag(HtmlTextWriterTag.Span);

            this.Repeater.RenderControl(writer);
            
            writer.RenderEndTag();
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            this.Repeater.ItemDataBound += new RepeaterItemEventHandler(this.Repeater_ItemDataBound);
            this.Repeater.ItemCommand += new RepeaterCommandEventHandler(this.Repeater_ItemCommand);
        }

        protected override object SaveViewState()
        {
            object[] viewState = new object[2];

            viewState[0] = base.SaveViewState();
            viewState[1] = this.DataKeyValues;

            return viewState;
        }

        protected override void LoadViewState(object savedState)
        {
            object[] viewState = (object[])savedState;

            base.LoadViewState(viewState[0]);
            this.DataKeyValues = (StringCollection)viewState[1];
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this.InitRepeater();
        }

        private void InitRepeater()
        {            
            this._repeater.ID = string.Format(CultureInfo.CurrentCulture, "rpt{0}", this.ID);
            this.Controls.Add(this._repeater);
        }

        private void AddItems()
        {
            AutoCompleteResultItem item = null;

            this.Items.Clear();

            for (int i = 0; i < this.Repeater.Items.Count; i++)
            {
                item = new AutoCompleteResultItem(this.Repeater.Items[i]);
                this.Items.Add(item);
            }
        }

        private void Repeater_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            string selectedValue = this.DataKeyValues[e.Item.ItemIndex];

            if (this.ItemCommand != null)
            {
                this.ItemCommand(this, new AutoCompleteResultCommandEventArgs(new AutoCompleteResultItem(e.Item), e.CommandName, e.CommandArgument, selectedValue));
            }

            this.AutoComplete.Text = selectedValue;
            this.ClearResult();
        }

        private void Repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType != ListItemType.AlternatingItem && e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.Separator) return;

            if (e.Item.ItemType != ListItemType.Separator)
            {
                this.DataKeyValues.Add(DataBinder.Eval(e.Item.DataItem, this.AutoComplete.DataKeyName).ToString());
            }

            if (this.ItemDataBound != null)
            {
                this.ItemDataBound(this, new AutoCompleteResultEventArgs(new AutoCompleteResultItem(e.Item)));
            }
        }

        private void ClearResult()
        {
            this.DataKeyValues.Clear();

            this.DataSource = null;
            this.DataBind();
        }
    }
}
